package com.huice.base;

import java.io.File;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.relevantcodes.extentreports.ExtentReports;
import org.openqa.selenium.Alert;
import org.openqa.selenium.UnhandledAlertException;
import org.openqa.selenium.WebDriver;
import org.testng.*;
import org.testng.xml.XmlSuite;

import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;

public class MyListener implements IReporter, ISuiteListener, IClassListener, ITestListener {
    //报告输出的目录
    public static final String REPORT_PATH = "report/" + String.valueOf(new Date().getTime()) + "/";

    public ExtentReports mExtent = null;
    public String mSestStamp = null;
    private ExtentTest test = null;


    /**
     * 对当前设备截图并返回
     */
    protected static String takeScreenshot(ITestResult result) {
        Object[] instances = result.getTestClass().getInstances(true);
        if (instances.length != 0) {
            TestBase testBase = instances[0] instanceof TestBase ? ((TestBase) instances[0]) : null;
            return testBase != null ? Screenshot.takeScreenshotToDir(testBase.getDriver(), REPORT_PATH) : null;
        }
        return null;
    }

    @Override
    public void generateReport(List<XmlSuite> arg0, List<ISuite> arg1,
                               String arg2) {
        FileEditor.copyFile(REPORT_PATH + mSestStamp + ".html", REPORT_PATH + "FinalReport.html");
    }


    @Override
    public void onStart(ISuite suite) {
        mSestStamp = DateHandler.getTimeStamp("yyyyMMddHHmmss");
        mExtent = ExtentManager.getReporter(REPORT_PATH + mSestStamp + ".html");
    }

    @Override
    public void onFinish(ISuite suite) {
        mExtent.flush();
        mExtent.close();
    }

    @Override
    public void onFinish(ITestContext context) {

        Iterator<ITestResult> listOfFailedTests = context.getFailedTests().getAllResults().iterator();

        while (listOfFailedTests.hasNext()) {
            ITestResult failedTest = listOfFailedTests.next();
            ITestNGMethod method = failedTest.getMethod();

            if (context.getFailedTests().getResults(method).size() > 1) {
                listOfFailedTests.remove();
            }
        }
    }

    @Override
    public void onBeforeClass(ITestClass testClass) {

    }

    @Override
    public void onAfterClass(ITestClass testClass) {

    }

    @Override
    public void onStart(ITestContext arg0) {

        System.out.println("正在为全部测试方法添加失败重跑机制");
        for (ITestNGMethod i : arg0.getAllTestMethods()) {
            i.setRetryAnalyzer(new RetryAnalyzer());
        }

    }

    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTestFailure(ITestResult result) {
        Throwable throwable = result.getThrowable();

        //如果是因为弹出Alert导致的出错，就自动关闭Alert
        if (throwable instanceof UnhandledAlertException) {
            Log.info("意外的弹出Alert导致程序出错", throwable);
            TestBase testBase = result.getInstance() instanceof TestBase ? ((TestBase) result.getInstance()) : null;
            if (testBase != null) {
                WebDriver driver = testBase.getDriver();
                Alert alert = testBase.locator.switchToAlert();
                if (alert != null) {
                    alert.accept();
                }
            }
        }

        Log.info(throwable.toString());
        test.log(LogStatus.FAIL, throwable.getMessage());

        String path = takeScreenshot(result);
        if (path != null) {
            ExtentTest extentTest = new ExtentTest("截图：", test.addScreenCapture(path));
            test.appendChild(extentTest);
        }

        mExtent.endTest(test);
    }

    @Override
    public void onTestSkipped(ITestResult result) {
        test.log(LogStatus.SKIP, result.getName());

        String path = takeScreenshot(result);
        if (path != null) {
            ExtentTest extentTest = new ExtentTest("截图：", test.addScreenCapture(path));
            test.appendChild(extentTest);
        }
        mExtent.endTest(test);

    }

    @Override
    public void onTestStart(ITestResult result) {
        // TODO Auto-generated method stub
        test = mExtent.startTest(result.getTestClass().getName() + "#" + result.getName());
    }

    @Override
    public void onTestSuccess(ITestResult result) {
        test.log(LogStatus.PASS, result.getName());
        mExtent.endTest(test);
    }
}
